PROJ_DIR := $(shell pwd)

CROSS_COMPILE := aarch64-linux-gnu-
QEMU_AARCH64 := qemu-system-aarch64

CC := ${CROSS_COMPILE}gcc
AS := ${CROSS_COMPILE}gcc
LD := ${CROSS_COMPILE}ld
OBJCOPY := ${CROSS_COMPILE}objcopy
OBJDUMP := ${CROSS_COMPILE}objdump
GDB := ${CROSS_COMPILE}gdb

APP_NAME := sweet_boot
APP := ${APP_NAME}.elf
SRC_DIR := src
OBJ_DIR := obj

INCLUDES = -I$(PROJ_DIR)/include

DEBUG_FLAGS = -g -ggdb3 -O0

ASFLAGS += ${DEBUG_FLAGS} -ffreestanding -Werror ${INCLUDES} -D__ASSEMBLY__
CFLAGS += ${DEBUG_FLAGS} -ffreestanding -Wall -Werror ${INCLUDES} -ffunction-sections -fdata-sections -Wno-unused-but-set-variable

LDFLAGS += --fatal-warnings -T armv8_qemu.ld

APP_C_SRC := $(wildcard $(SRC_DIR)/*.c)
APP_ASM_SRC := $(wildcard $(SRC_DIR)/*.S)

OBJ_FILES := $(APP_C_SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
OBJ_FILES += $(APP_ASM_SRC:$(SRC_DIR)/%.S=$(OBJ_DIR)/%.o)
DEP_FILES := $(OBJ_FILES:%=%.d)

.PHONY: all clean

all: $(APP)

$(APP): $(OBJ_DIR) $(OBJ_FILES)
	$(LD) $(LDFLAGS) -o $@ $(OBJ_FILES)
	$(OBJCOPY) -O binary $@ ${APP_NAME}.bin
	$(OBJDUMP) -S -D $@ > ${APP_NAME}.dump

$(OBJ_DIR)/%.o : $(SRC_DIR)/%.c
	$(CC) $(CFLAGS) -c -o $@ $<

$(OBJ_DIR)/%.o : $(SRC_DIR)/%.S
	$(CC) $(ASFLAGS) -c -o $@ $<

$(OBJ_DIR):
	mkdir -p $@

-include $(DEP_FILES)

QEMU_DEV := -machine virt,secure=on,gic-version=3,virtualization=off -cpu cortex-a53

clean:
	@echo "CLEAN"
	rm -rf ${OBJ_DIR} ${APP_NAME}.dump ${APP_NAME}.elf ${APP_NAME}.bin

run:
	$(QEMU_AARCH64) $(QEMU_DEV) -bios ${APP_NAME}.bin -serial stdio

gdb:
	$(GDB) -ex "symbol ${APP_NAME}.elf" -ex "target remote localhost:1234"

debug:
	$(QEMU_AARCH64) $(QEMU_DEV) -bios ${APP_NAME}.bin -gdb tcp::1234 -nographic -S
